/*
 * Copyright (C) 2013 AndXmppSDK Project <hljdrl@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.drl.xmpp;

import java.util.ArrayList;
import java.util.List;

import org.drl.xmpp.impl.TalkLoginStateListener;
import org.jivesoftware.smack.XMPPConnection;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

/**
 * 
 * XMPP第一入口类，总的入口.
 * 
 * @author hljdrl@gmail.com
 */
public abstract class TalkClient {
	public static final String TAG = "TalkClient";
	private static boolean saveTalkSQLite = false;
	
	boolean debug = false;
	Context mContext;
	UserInfo mUserInfo;
	protected String mHost;
	protected int mPort;
	private String serverAddress;
	protected static List<TalkLoginStateListener> mTalkLoginStateListener = new ArrayList<TalkLoginStateListener>();
	Handler updataHandler;
	public TalkClient(Context ctx) {
		mContext = ctx;
		updataHandler = new TalkHandler(this);
	}
	public final  void addTalkLoginStateListener(TalkLoginStateListener listener){
		if(listener!=null){
			synchronized (mTalkLoginStateListener) {
				mTalkLoginStateListener.add(listener);
			}
		}
	}
	public final  void removeTalkLoginStateListener(TalkLoginStateListener listener){
		if(listener!=null){
			synchronized (mTalkLoginStateListener) {
				mTalkLoginStateListener.remove(listener);
			}
		}
	}
	protected final  void setLoginState(int  state,String text){
		Message msg  = updataHandler.obtainMessage(state);
		msg.obj = text;
		updataHandler.sendMessage(msg);
	}
	
	void notifyTalkLoginStateListeners(int  state,String text)
	{
		if(mTalkLoginStateListener!=null){
			for(TalkLoginStateListener l: mTalkLoginStateListener){
				try{
					l.OnChageStatus(state,text);
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}
	}
	public final static void setSaveTalkSQLite(boolean state){
		saveTalkSQLite = state;
	}
	public final static boolean isSaveTalkSQLite()
	{
		return saveTalkSQLite;
	}
	public final Context getContext()
	{
		return mContext;
	}
	public final String getServerAddress() {
		return serverAddress;
	}

	protected final void setServerAddress(String address) {
		this.serverAddress = address;
	}
	/**
	 * 返回聊天管理器
	 * @return 返回聊天管理器
	 */
	abstract public TChatManager getChatManager();

	/**
	 * 返回花名册(好友列表)管理器
	 * @return 返回花名册(好友列表)管理器
	 */
	abstract public RosterManager getRosterManager();

	/**
	 * 返回用户以及好友的登录状态-管理器
	 * @return 返回用户以及好友的登录状态-管理器
	 */
	abstract public PresenceManager getPresenceManager();

	/**
	 * 返回VCard名片,登录用户、好友的个人名片信息-管理器
	 * @return 返回VCard名片,登录用户、好友的个人名片信息-管理器
	 */
	abstract public VCardManager getVCardManager();

	/**
	 * 返回用户搜索-管理器
	 * @return 返回用户搜索-管理器
	 */
	abstract public SeachManager getSeachManager();

	/**
	 * 当前用户信息
	 * @return 当前用户信息
	 */
	public final  UserInfo getUserInfo(){
		return mUserInfo;
	}
	/**
	 * 当前用户登录状态
	 * @return 当前用户登录状态
	 */
	public abstract TPresence getTPresence();
	/**
	 * 设置当前登录的用户对象
	 * @param user 设置当前登录的用户对象
	 */
	public final void setUserInfo(UserInfo user){
		this.mUserInfo = user;
	}
	/**
	 * 异步连接并登录xmpp账户
	 */
	public abstract void connectAsync();

	/**
	 * 返回是否连接XMPP服务器
	 * @return 返回是否连接XMPP服务器
	 */
	public abstract boolean connect();

	/**
	 * 登录到消息服务器,登录成功返回true，fasel代表登录失败.
	 * @return 登录到消息服务器,登录成功返回true，fasel代表登录失败.
	 */
	public abstract boolean login();

	/**
	 * 同步登录当前账户
	 */
	public abstract boolean connectSync();

	/**
	 * 检查当前账户是否登录并验证
	 */
	public final  boolean isAuthentificated(){
		return getConnection() != null && getConnection().isAuthenticated();
	}

	/**
	 * 注销XMPP连接，并释放所有相关接口资源.
	 */
	public abstract void disconnect();

	/**
	 * 更改当前账户登录状态
	 */
	public abstract void changeStatus(TPresence status);

	/**
	 * 设置连接服务器信息
	 * @param host 服务器地址
	 * @param port 服务器断开
	 */
	public final void setHost(String host, int port){
		this.mHost = host;
		this.mPort = port;
	}

	/**
	 * 设置用户头像,filename 图片的路径
	 * @param fileName 头像的文件路径
	 * @return 返回是否设置头像成功,这个方法会阻塞,请UI层做好异步处理.
	 */
	abstract boolean setAvatar(String fileName);

	/**
	 * XMPP连接的ID,可用来做统计或者二次开发,在xmpp-service中也存在客户端的ConnectionID.
	 * @return XMPP连接的ID,可用来做统计或者二次开发,在xmpp-service中也存在客户端的ConnectionID.
	 */
	abstract String getConnectionID();

	/**
	 * 给指定好友发送文件.
	 * @param user 好友名字,好友的JID.
	 * @param fileName 文件的完整路径.
	 * @param mDescript 文件的描述信息.
	 */
	public abstract void sendFile(String user, String fileName, String mDescript);

	XMPPConnection connection = null;

	final void setXMPPConnection(XMPPConnection xmpp) {
		connection = xmpp;
	}

	final XMPPConnection getConnection() {
		return connection;
	}

	/**
	 * 设置是否显示调试日志信息
	 * @param is 调试信息开关
	 */
	final public void setDebug(boolean is) {
		debug = is;
	}

	final public boolean isDebug() {
		return debug;
	}
	
	final public boolean isConnected() {
		return connection != null && connection.isConnected();
	}

}
